﻿using System;
using System.Collections.Generic;
using Helpers;

namespace SharedTypes
{
    /// <summary>
    /// Класс реализует параметр алгоритма исполнительного файла, который
    /// может быть адаптирован.
    /// </summary>
    public class Parameter : IParameter, ICloneable
    {
        #region Members
        /// <summary>
        /// Порядковый номер параметра.
        /// </summary>
        private byte orderNum;

        /// <summary>
        /// Короткое имя параметра.
        /// </summary>
        private string shortDescription;

        /// <summary>
        /// Описание параметра.
        /// </summary>
        private string description;

        /// <summary>
        /// Список допустимых значений параметра.
        /// </summary>
        private IList<AcceptableValue> acceptableValues;

        /// <summary>
        /// Текущее значение параметра.
        /// </summary>
        private AcceptableValue m_currentAcceptValues;

        /// <summary>
        /// Текущее значение параметра.
        /// TODO: make mb not object
        /// </summary>
        private object currentValues;

        /// <summary>
        /// Значение после заданого значения.
        /// </summary>
        private string valueEnd;

        /// <summary>
        /// Текущее значение по умолчанию.
        /// </summary>
        private object defValue;

        /// <summary>
        /// Объект генератора случайных чисел.
        /// </summary>
        private static Random randomiser;
        #endregion /// Members

        #region Properties

        /// <summary>
        /// Порядковый номер параметра.
        /// </summary>
        public byte OrderNum 
        { 
            get { return orderNum; } 
        }

        /// <summary>
        /// Короткое имя параметра.
        /// </summary>
        public string Name
        {
            get { throw new NotImplementedException("Reserved"); }
        }

        /// <summary>
        /// Условное соединение.
        /// </summary>
        public string ConditionLink
        {
            get { throw new NotImplementedException("Reserved"); }
        }

        /// <summary>
        /// Короткое имя параметра.
        /// </summary>
        public string ShortDescription
        {
            get { return shortDescription; }
        }

        /// <summary>
        /// Описание параметра.
        /// </summary>
        public string Description
        {
            get { return description; }
        }

        /// <summary>
        /// Список допустимых значений параметра.
        /// </summary>
        public IList<AcceptableValue> AcceptableValues
        {
            get { return acceptableValues; }
        }

        /// <summary>
        /// Количество допустимых значений.
        /// </summary>
        public int NumOfAcceptableValues
        {
            get { return acceptableValues.Count; }
        }

        /// <summary>
        /// Текущий параметр.
        /// </summary>
        public AcceptableValue CurrentAcceptValue
        {
            get { return m_currentAcceptValues; }
            set { m_currentAcceptValues = value; }
        }

        /// <summary>
        /// Текущее значение параметра.
        /// </summary>
        public object CurrentValue
        {
            get { return currentValues; }
            set { currentValues = value; }
        }

        /// <summary>
        /// Reserved. Является ли параметр ключевым
        /// </summary>
        public bool IsParamKey
        {
            get { throw new NotImplementedException("Reserved"); }
        }

        /// <summary>
        /// Тип параметра
        /// </summary>
        public int Type
        {
            get { throw new NotImplementedException("Reserved"); }
        }

        /// <summary>
        /// Заверешение после значения.
        /// </summary>
        public string ValueEnd
        {
            get { return valueEnd; }
        }

        /// <summary>
        /// Разделитель.
        /// </summary>
        public string Separator
        {
            get { throw new NotImplementedException("Reserved"); }
        }

        /// <summary>
        /// Значение по умолчанию.
        /// </summary>
        public object DefaultValue
        {
            get { return defValue; }
        }
        #endregion // Properties

        #region Constructor
        /// <summary>
        /// Конструктор.
        /// </summary>
        /// <param name="order">Порядковый номер.</param>
        /// <param name="name">Краткое описание параметра.</param>
        /// <param name="description">Описание параметра.</param>
        /// <param name="values">Список допустимых значений.</param>
        /// <param name="defaultValue">Значение по умолчанию.</param>
        public Parameter(byte order, string shortDescription, string description, IList<AcceptableValue> values, object defaultValue)
        {
            orderNum = order;
            this.shortDescription = shortDescription;
            this.description = description;
            acceptableValues = values;
            currentValues = null;
            defValue = defaultValue;
            randomiser = new Random(DateTime.Now.Millisecond);
        }
        #endregion // Constructor

        #region Methods
        /// <summary>
        /// Функция, присваивающая параметра случайное значение
        /// из списка допустимых.
        /// </summary>
        public void PlaceParamInRandomState()
        {
            int id = randomiser.Next(0, acceptableValues.Count - 1);
            CurrentAcceptValue = acceptableValues[id];
        }

        /// <summary>
        /// Функция, присваивающая параметра случайное значение
        /// из списка допустимых.
        /// </summary>
        public void PlaceValuesInRandomState()
        {
            PlaceParamInRandomState();
            int id = randomiser.Next(0, ((IList<object>)CurrentAcceptValue.values).Count - 1);
            CurrentValue = ((IList<object>)CurrentAcceptValue.values)[id];
        }

        /// <summary>
        /// Функция, создающая глубокую копию текущего объекта.
        /// </summary>
        /// <returns>Копия текущего объекта.</returns>
        public object Clone()
        {
            IList<AcceptableValue> values = new List<AcceptableValue>();
            foreach (AcceptableValue acceptableValue in acceptableValues)
            {
               values.Add(acceptableValue); 
            }
            Parameter toRet = new Parameter(orderNum, shortDescription, description, values, ObjectCloner.CloneObject(defValue));
            toRet.currentValues = currentValues.ToString();
            return toRet;
        }
        #endregion // Methods

        
    }
}
